package main

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/gin-gonic/gin"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	_ "github.com/spf13/viper/remote"
	"go.uber.org/zap"
	"net/http"
)

func main() {
	initViperV1()
	initLogger()
	keys:=viper.AllKeys()
	println(keys)
	setting:=viper.AllSettings()
	fmt.Println(setting)
	app := InitApp()
	for _, c:=range app.consumers{
		err:=c.Start()
		if err!=nil{
			panic(any(err))
		}
	}
	server:=app.server
	server.GET("/hello", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "Hello! Boy!")
	})
	server.Run(":8080")
}

func initLogger() {
	logger, err := zap.NewDevelopment()
	if err!=nil {
		panic(any(err))
	}
	zap.ReplaceGlobals(logger)
}


func initViper() {
	// 配置文件名字和后缀类型
	viper.SetConfigName("dev")
	viper.SetConfigType("yaml")
	viper.AddConfigPath("./config")
	// 读取配置文件到viper中
	err:=viper.ReadInConfig()
	if err!=nil{
		panic(any(err))
	}
	// 多套配置文件，在模块中
	//otherViper:=viper.New()
	//otherViper.SetConfigName("myjson")
	//otherViper.SetConfigType("yaml")
	//otherViper.AddConfigPath("./config")
}

func initViperV1() {
	cfile := pflag.String("config",
		"config/config.yaml", "指定配置文件路径")
	// 命令行解析接收
	pflag.Parse()
	viper.SetConfigFile(*cfile)
	// 监听文件变更
	viper.WatchConfig()
	viper.OnConfigChange(func(in fsnotify.Event) {
		fmt.Println(in.Name, in.Op)
	})
	err:=viper.ReadInConfig()
	if err!=nil{
		panic(any(err))
	}
}

func initViperRemote() {
	viper.SetConfigType("yaml")
	err:=viper.AddRemoteProvider("etcd3",
		"127.0.0.1:12379", "/webook")
	if err!=nil{
		panic(any(err))
	}

	err=viper.ReadRemoteConfig()
	if err!=nil{
		panic(any(err))
	}
}

//
//func initWebServer() *gin.Engine {
//	r := gin.Default()
//	//r.Use(func(ctx *gin.Context) {
//	//	println("这是第一个middleware")
//	//})
//	//r.Use(func(ctx *gin.Context) {
//	//	println("这是第二个middleware")
//	//})
//	// 解决前后端分离的跨域问题
//	r.Use(cors.New(cors.Config{
//		// AllowOrigins: []string{"https://localhost:3000"},
//		AllowMethods: []string{"PUT"},
//		AllowHeaders: []string{"Content-Type", "Authorization"},
//		// 不加这个，前端拿不到
//		ExposeHeaders: []string{"x-jwt-token"},
//		// 是否允许带 cookie 之类的东西
//		AllowCredentials: true,
//		AllowOriginFunc: func(origin string) bool {
//			if strings.HasPrefix(origin, "http://localhost") {
//				return true
//			}
//			return strings.Contains(origin, "yourcompany.com")
//		},
//		MaxAge: 12 * time.Hour,
//	}))
//
//	redisClient := redis.NewClient(&redis.Options{
//		Addr:     config.Config.Redis.Addr,
//		Password: "",
//		DB:       1,
//	})
//	r.Use(ratelimit.NewBuilder(redisClient, time.Second, 100).Build())
//	// 步骤1
//	//store := cookie.NewStore([]byte("secret"))
//	// 可在网页上搜索 生成随机密钥
//	//store := memstore.NewStore([]byte("32位或64位的authentication key"), []byte("encryption key"))
//	// 使用 gin redis session Store
//	store, err := session_redis.NewStore(16, "tcp", "localhost:6379", "",
//		// 身份认证 key
//		[]byte("qJfZR1psrw3PXpT1aPbeRoUl0eLtdBH2bcFobbf9MKhdbd8MoR2V046H0obQd2tc"),
//		// 数据加密 key
//		[]byte("YRUjPBZzysaoAxAx31f5pXMwithO9AR2FX6ZspHzSKbtLkH2JcIf6PyeQwQyR4bS"))
//	if err != nil {
//		println(err)
//	}
//	r.Use(sessions.Sessions("mysession", store))
//	// 步骤3
//	//r.Use(middleware.NewLoginMiddlewareBuilder().
//	//	IgnorePaths("/users/login").
//	//	IgnorePaths("/users/signup").Build())
//	r.Use(middleware.NewLoginJWTMiddlewareBuilder().
//		IgnorePaths("/users/login").
//		IgnorePaths("/users/login_sms").
//		IgnorePaths("/users/login_sms/code/send").
//		IgnorePaths("/users/signup").Build())
//
//	return r
//}

//func initRedis() redis.Cmdable {
//	redisClient:=redis.NewClient(&redis.Options{
//		Addr: config.Config.Redis.Addr,
//	})
//	return redisClient
//}

//func initUser(db *gorm.DB, rdb redis.Cmdable) *web.UserHandler {
//	ud := dao.NewUserDAO(db)
//	uc := cache.NewUserCache(rdb, time.Minute * 10)
//	repo := repository.NewUserRepository(ud, uc)
//	svc := service.NewUserService(repo)
//	codeCache:=cache.NewCodeCache(rdb)
//	codeRepo:= repository.NewCodeRepository(codeCache)
//	smsSvc:=memory.NewService()
//	codeSvc := service.NewCodeService(codeRepo, smsSvc)
//	u := web.NewUserHanlder(svc, codeSvc) // 取地址
//	return u
//}

//func initDB() *gorm.DB {
//	//db, err := gorm.Open(mysql.Open("root:123456@tcp(webook-mysql:13306)/webook"))
//	db, err := gorm.Open(mysql.Open(config.Config.DB.DSN))
//	if err != nil {
//		// 初始化出错，应用就不要启动了
//		panic(err.(any))
//	}
//	// 自动迁移，确保数据库表格与结构同步。它会创建新表、添加缺失的列和索引，但不会删除多余列以保护数据
//	err = dao.InitTables(db)
//	if err != nil {
//		panic(err.(any))
//	}
//	return db
//}